import 'dart:math';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';

class Utils {
  // 判断字符串是否为纯数字
  static bool isNumeric(String text) {
    return RegExp(r'^\d+$').hasMatch(text);
  }

  // 判断字符串是否为非中文
  static bool isNotChinese(String text) {
    return !RegExp(r'[\u4e00-\u9fa5]').hasMatch(text);
  }

  // 将 Uint8List 转换为 int
  static int uint8List2Int(
    Uint8List uint8List, {
    Endian endian = Endian.little,
  }) {
    if (uint8List.isEmpty) {
      throw ArgumentError('Uint8List cannot be empty');
    }
    int result = 0;
    for (int i = 0; i < uint8List.length; i++) {
      int byte = uint8List[i];
      if (endian == Endian.little) {
        result |= (byte << (i * 8));
      } else {
        result |= (byte << ((uint8List.length - 1 - i) * 8));
      }
    }
    return result;
  }

  // int 转为两个字节的 Uint8List
  static Uint8List intTo2Uint8List(int value, {Endian endian = Endian.little}) {
    if (value < 0 || value > 0xFFFF) {
      throw ArgumentError('Value must be in the range of 0 to 65535');
    }
    // 创建一个长度为2的Uint8List
    Uint8List bytes = Uint8List(2);
    // 使用ByteData来设置字节
    ByteData byteData = ByteData.sublistView(bytes);
    // 根据字节序设置值
    if (endian == Endian.little) {
      byteData.setUint16(0, value, Endian.little);
    } else {
      byteData.setUint16(0, value, Endian.big);
    }
    return bytes;
  }

  // int 转换为 Uint8List
  static Uint8List int2Uint8List(int number, {Endian endian = Endian.little}) {
    // 计算需要的字节数
    int byteCount = (number.bitLength + 7) ~/ 8;

    // 创建 ByteData
    ByteData byteData = ByteData(byteCount);

    // 将整数写入 ByteData
    for (int i = 0; i < byteCount; i++) {
      int offset = (byteCount - 1 - i) * 8; // 大端序
      byteData.setUint8(i, (number >> offset) & 0xFF);
    }

    // 转换为 Uint8List
    return byteData.buffer.asUint8List();
  }

  // int64 转换为 Uint8List
  static Uint8List int64ToBytes(int value) {
    if (value.bitLength > 63) {
      throw ArgumentError('Value exceeds 64-bit range');
    }
    // 创建8字节的ByteBuffer
    final ByteData byteData = ByteData(8);

    // 将int写入ByteData（大端序或小端序）
    byteData.setInt64(0, value, Endian.little);

    // 转换为Uint8List
    return byteData.buffer.asUint8List();
  }

  // int32 转换为 Uint8List
  static Uint8List int32ToBytes(int value) {
    if (value.bitLength > 31) {
      throw ArgumentError('Value exceeds 32-bit range');
    }
    // 创建4字节的ByteBuffer
    final ByteData byteData = ByteData(4);
    // 将int写入ByteData（大端序或小端序）
    byteData.setInt32(0, value, Endian.little);
    // 转换为Uint8List
    return byteData.buffer.asUint8List();
  }

  // Uint8List 计算crc32
  static int calculateCrc32(
    List<int> data, {
    int initCrc = 0xFFFFFFFF,
    int xorOut = 0xFFFFFFFF,
  }) {
    var crc = initCrc;
    for (var i = 0; i < data.length; i++) {
      crc = crc32Table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8);
    }
    return crc ^ xorOut;
  }

  // 生成4字节的随机数
  static Uint8List generateSecureRandomUint8List4Bytes() {
    final random = Random.secure();
    return Uint8List.fromList(List.generate(4, (_) => random.nextInt(256)));
  }

  // 将 Uint8List 转换为字符串
  static String uint8List2HexString(Uint8List uint8List) {
    return uint8List
        .map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase())
        .join();
  }

  // 将hex字符串转Uint8List
  static Uint8List hexString2Uint8List(String hexString) {
    // 去除可能的空白字符
    hexString = hexString.replaceAll(RegExp(r'\s'), '');

    // 将字符串分割为每两个字符一组
    List<String> hexPairs = [];
    for (int i = 0; i < hexString.length; i += 2) {
      hexPairs.add(hexString.substring(i, i + 2));
    }

    // 将每对十六进制字符转换为字节
    Uint8List result = Uint8List(hexPairs.length);
    for (int i = 0; i < hexPairs.length; i++) {
      result[i] = int.parse(hexPairs[i], radix: 16);
    }

    return result;
  }

  // 计算非零字节的数量
  static int countNonZeroBytes(Uint8List bytes, {int? offset}) {
    // 如果没有指定n，则检查整个列表
    final length = offset ?? bytes.length;
    // 确保n不超过列表长度
    final end = length.clamp(0, bytes.length);

    int count = 0;
    for (int i = 0; i < end; i++) {
      if (bytes[i] != 0) {
        count++;
      }
    }
    return count;
  }

  // 获取最后一个非零字节的值
  static int getLastNonZeroByteValue(Uint8List bytes) {
    for (int i = bytes.length - 1; i >= 0; i--) {
      if (bytes[i] != 0x00) {
        return bytes[i]; // 直接返回十进制值（0-255）
      }
    }
    return 0; // 如果全部是 0x00，返回 0 或其他默认值
  }

  // 生成固定长度的16字节数组
  static Uint8List generateFixed16Bytes(String input) {
    // 1. 将 appId 转换为字节数组
    final bytes = utf8.encode(input);

    // 2. 使用 SHA-256 哈希（确保输出长度足够）
    final hash = sha256.convert(bytes).bytes;

    // 3. 取前 16 字节（如果哈希长度不足 16，理论上不会发生）
    return Uint8List.fromList(hash.take(16).toList());
  }

  /// 将高位整数和低位整数组合成uint32
  static int intCombineToUint32(int highVal, int lowVal) {
    if (highVal < 0 || highVal > 0xFFFF || lowVal < 0 || lowVal > 0xFFFF) {
      throw ArgumentError('高低位必须在0到65535之间');
    }
    // 将高16位和低16位组合成uint32
    return (highVal << 16) | lowVal;
  }

  /// 将int转为四个字节的Uint8List，高位在前，低位在后
  static Uint8List getUint32Bytes(int value) {
    if (value < 0 || value > 0xFFFFFFFF) {
      throw ArgumentError('Value must be in the range of 0 to 4294967295');
    }
    // 创建4字节的ByteBuffer
    final ByteData byteData = ByteData(4);
    // 将int写入ByteData（大端序或小端序）
    byteData.setInt32(0, value, Endian.big);
    // 转换为Uint8List
    return byteData.buffer.asUint8List();
  }

  // 判断两个版本号之间的大小关系，1 表示 version1 > version2，-1 表示 version1 < version2，0 表示相等
  static int compareVersions(String version1, String version2) {
    List<int> v1Parts = version1.split('.').map(int.parse).toList();
    List<int> v2Parts = version2.split('.').map(int.parse).toList();

    int length =
        v1Parts.length > v2Parts.length ? v1Parts.length : v2Parts.length;

    for (int i = 0; i < length; i++) {
      int part1 = i < v1Parts.length ? v1Parts[i] : 0;
      int part2 = i < v2Parts.length ? v2Parts[i] : 0;

      if (part1 > part2) return 1;
      if (part1 < part2) return -1;
    }
    return 0; // 相等
  }
}

// crc32校验表
const crc32Table = [
  0x00000000,
  0x77073096,
  0xEE0E612C,
  0x990951BA,
  0x076DC419,
  0x706AF48F,
  0xE963A535,
  0x9E6495A3,
  0x0EDB8832,
  0x79DCB8A4,
  0xE0D5E91E,
  0x97D2D988,
  0x09B64C2B,
  0x7EB17CBD,
  0xE7B82D07,
  0x90BF1D91,
  0x1DB71064,
  0x6AB020F2,
  0xF3B97148,
  0x84BE41DE,
  0x1ADAD47D,
  0x6DDDE4EB,
  0xF4D4B551,
  0x83D385C7,
  0x136C9856,
  0x646BA8C0,
  0xFD62F97A,
  0x8A65C9EC,
  0x14015C4F,
  0x63066CD9,
  0xFA0F3D63,
  0x8D080DF5,
  0x3B6E20C8,
  0x4C69105E,
  0xD56041E4,
  0xA2677172,
  0x3C03E4D1,
  0x4B04D447,
  0xD20D85FD,
  0xA50AB56B,
  0x35B5A8FA,
  0x42B2986C,
  0xDBBBC9D6,
  0xACBCF940,
  0x32D86CE3,
  0x45DF5C75,
  0xDCD60DCF,
  0xABD13D59,
  0x26D930AC,
  0x51DE003A,
  0xC8D75180,
  0xBFD06116,
  0x21B4F4B5,
  0x56B3C423,
  0xCFBA9599,
  0xB8BDA50F,
  0x2802B89E,
  0x5F058808,
  0xC60CD9B2,
  0xB10BE924,
  0x2F6F7C87,
  0x58684C11,
  0xC1611DAB,
  0xB6662D3D,
  0x76DC4190,
  0x01DB7106,
  0x98D220BC,
  0xEFD5102A,
  0x71B18589,
  0x06B6B51F,
  0x9FBFE4A5,
  0xE8B8D433,
  0x7807C9A2,
  0x0F00F934,
  0x9609A88E,
  0xE10E9818,
  0x7F6A0DBB,
  0x086D3D2D,
  0x91646C97,
  0xE6635C01,
  0x6B6B51F4,
  0x1C6C6162,
  0x856530D8,
  0xF262004E,
  0x6C0695ED,
  0x1B01A57B,
  0x8208F4C1,
  0xF50FC457,
  0x65B0D9C6,
  0x12B7E950,
  0x8BBEB8EA,
  0xFCB9887C,
  0x62DD1DDF,
  0x15DA2D49,
  0x8CD37CF3,
  0xFBD44C65,
  0x4DB26158,
  0x3AB551CE,
  0xA3BC0074,
  0xD4BB30E2,
  0x4ADFA541,
  0x3DD895D7,
  0xA4D1C46D,
  0xD3D6F4FB,
  0x4369E96A,
  0x346ED9FC,
  0xAD678846,
  0xDA60B8D0,
  0x44042D73,
  0x33031DE5,
  0xAA0A4C5F,
  0xDD0D7CC9,
  0x5005713C,
  0x270241AA,
  0xBE0B1010,
  0xC90C2086,
  0x5768B525,
  0x206F85B3,
  0xB966D409,
  0xCE61E49F,
  0x5EDEF90E,
  0x29D9C998,
  0xB0D09822,
  0xC7D7A8B4,
  0x59B33D17,
  0x2EB40D81,
  0xB7BD5C3B,
  0xC0BA6CAD,
  0xEDB88320,
  0x9ABFB3B6,
  0x03B6E20C,
  0x74B1D29A,
  0xEAD54739,
  0x9DD277AF,
  0x04DB2615,
  0x73DC1683,
  0xE3630B12,
  0x94643B84,
  0x0D6D6A3E,
  0x7A6A5AA8,
  0xE40ECF0B,
  0x9309FF9D,
  0x0A00AE27,
  0x7D079EB1,
  0xF00F9344,
  0x8708A3D2,
  0x1E01F268,
  0x6906C2FE,
  0xF762575D,
  0x806567CB,
  0x196C3671,
  0x6E6B06E7,
  0xFED41B76,
  0x89D32BE0,
  0x10DA7A5A,
  0x67DD4ACC,
  0xF9B9DF6F,
  0x8EBEEFF9,
  0x17B7BE43,
  0x60B08ED5,
  0xD6D6A3E8,
  0xA1D1937E,
  0x38D8C2C4,
  0x4FDFF252,
  0xD1BB67F1,
  0xA6BC5767,
  0x3FB506DD,
  0x48B2364B,
  0xD80D2BDA,
  0xAF0A1B4C,
  0x36034AF6,
  0x41047A60,
  0xDF60EFC3,
  0xA867DF55,
  0x316E8EEF,
  0x4669BE79,
  0xCB61B38C,
  0xBC66831A,
  0x256FD2A0,
  0x5268E236,
  0xCC0C7795,
  0xBB0B4703,
  0x220216B9,
  0x5505262F,
  0xC5BA3BBE,
  0xB2BD0B28,
  0x2BB45A92,
  0x5CB36A04,
  0xC2D7FFA7,
  0xB5D0CF31,
  0x2CD99E8B,
  0x5BDEAE1D,
  0x9B64C2B0,
  0xEC63F226,
  0x756AA39C,
  0x026D930A,
  0x9C0906A9,
  0xEB0E363F,
  0x72076785,
  0x05005713,
  0x95BF4A82,
  0xE2B87A14,
  0x7BB12BAE,
  0x0CB61B38,
  0x92D28E9B,
  0xE5D5BE0D,
  0x7CDCEFB7,
  0x0BDBDF21,
  0x86D3D2D4,
  0xF1D4E242,
  0x68DDB3F8,
  0x1FDA836E,
  0x81BE16CD,
  0xF6B9265B,
  0x6FB077E1,
  0x18B74777,
  0x88085AE6,
  0xFF0F6A70,
  0x66063BDE,
  0x11010B5C,
  0x8F659EFF,
  0xF862AE69,
  0x616BFFD3,
  0x166CCF45,
  0xA00AE278,
  0xD70DD2EE,
  0x4E048354,
  0x3903B3C2,
  0xA7672661,
  0xD06016F7,
  0x4969474D,
  0x3E6E77DB,
  0xAED16A4A,
  0xD9D65ADC,
  0x40DF0B66,
  0x37D83BF0,
  0xA9BCAE53,
  0xDEBB9EC5,
  0x47B2CF7F,
  0x30B5FFE9,
  0xBDBDF21C,
  0xCABAC28A,
  0x53B39330,
  0x24B4A3A6,
  0xBAD03605,
  0xCDD70693,
  0x54DE5729,
  0x23D967BF,
  0xB3667A2E,
  0xC4614AB8,
  0x5D681B02,
  0x2A6F2B94,
  0xB40BBE37,
  0xC30C8EA1,
  0x5A05DF1B,
  0x2D02EF8D
];

/// debugPrintMap(data);
/// debugPrintMap(data, indent: '    '); // 使用4空格缩进
/// debugPrintMap(data, wrapWidth: 100); // 设置换行宽度
void debugPrintMap(
  Map map, {
  String indent = '  ',
  int? wrapWidth,
  bool onlyInDebug = true,
}) {
  if (onlyInDebug && !kDebugMode) {
    return;
  }

  try {
    String formatted = JsonEncoder.withIndent(indent).convert(map);
    debugPrint(formatted, wrapWidth: wrapWidth);
  } catch (e) {
    // 如果包含不能直接序列化的对象，使用 toString()
    debugPrint('Error formatting map: $e');
    debugPrint(map.toString(), wrapWidth: wrapWidth);
  }
}
